<template>
  <div class="app-container">
    <el-card class="main-card">
      <div class="flex-container">
        <!-- 左侧表格区域 -->
        <div class="table-wrapper">
          <el-table
            :data="filteredCourses"
            stripe
            border
            style="width: 100%; height: 100%"
            class="custom-table"
            @row-dblclick="handleDblClick"
          >
            <el-table-column prop="Dept" label="院系" width="200" sortable />
            <el-table-column prop="Nature" label="课程性质" width="110" sortable />
            <el-table-column prop="Crd" label="学分" width="100" sortable />
            <el-table-column prop="Code" label="课程代码" width="120" sortable />
            <el-table-column prop="Sim.Assess" label="考核" width="120" sortable />
            <el-table-column prop="Title" label="课程名称" sortable>
              <template #default="{ row }">
                <el-button type="text" @click="handleClick(row)">{{ row.Title }}</el-button>
              </template>
            </el-table-column>
            <template #empty>
              <div class="empty-container" style="margin-top: 100px">
                <el-icon :size="50" color="#909399" :class="{ 'spin-icon': isLoading }"
                  ><Loading v-if="isLoading"
                /></el-icon>
                <p>{{ isLoading ? "加载中..." : `暂无数据` }}</p>
              </div>
            </template>
          </el-table>
        </div>

        <!-- 右侧筛选区域 -->
        <el-card class="filter-card">
          <el-popover v-model:visible="updateDialogVisible" width="11%" trigger="click">
            <p style="text-align: center">需要更新数据吗？</p>
            <div style="display: flex; justify-content: space-between; margin-top: 10px">
              <el-button type="" size="small" @click="updateDialogVisible = false">取消</el-button>
              <el-button type="" size="small" @click="redirectToSEIG">查看数据源</el-button>
              <el-button type="primary" size="small" @click="updateCourseTable">确认</el-button>
            </div>
            <template #reference>
              <div class="filter-header">
                <el-tag type="success" class="update-time">{{ updateTime }}</el-tag>
              </div>
            </template>
          </el-popover>

          <el-form class="filter-form" label-position="right" label-width="100px">
            <el-form-item label="教学系" class="inline-form-item">
              <el-select v-model="filters.Dept" placeholder="请选择教学系" clearable>
                <el-option v-for="dept in departments" :key="dept" :label="dept" :value="dept" />
              </el-select>
            </el-form-item>

            <el-form-item label="课程性质" class="inline-form-item">
              <el-select v-model="filters.courseType" placeholder="请选择课程性质" clearable>
                <el-option v-for="Nature in courseTypes" :key="Nature" :label="Nature" :value="Nature" />
              </el-select>
            </el-form-item>

            <el-form-item label="课程代码" class="inline-form-item">
              <el-input v-model="filters.courseCode" placeholder="请输入课程代码" clearable />
            </el-form-item>

            <el-form-item label="学分" class="inline-form-item">
              <el-select v-model="filters.Crd" placeholder="请选择学分" clearable>
                <el-option v-for="Crd in credits" :key="Crd" :label="Crd" :value="Crd" />
              </el-select>
            </el-form-item>

            <el-form-item label="教师" class="inline-form-item">
              <el-select v-model="filters.Teacher" placeholder="请选择教师" clearable filterable>
                <el-option v-for="teacher in teachers" :key="teacher" :label="teacher" :value="teacher" />
              </el-select>
            </el-form-item>

            <el-form-item label="考核方式" class="inline-form-item">
              <el-select v-model="filters.Assess" placeholder="请选择考核方式" clearable filterable>
                <el-option v-for="ass in Assess" :key="ass" :label="ass" :value="ass" />
              </el-select>
            </el-form-item>

            <el-form-item label="课程名称" class="inline-form-item">
              <el-input v-model="filters.courseName" placeholder="请输入课程名称" clearable />
            </el-form-item>

            <div class="action-buttons">
              <el-pagination
                :total="filteredCourses.length"
                :page-size="filteredCourses.length"
                layout="total"
                style="text-align: right; margin-right: 0px"
              />
              <!-- <el-button Nature="primary" @click="search">查询</el-button> -->
              <el-button @click="reset" Nature="info" plain style="margin-right: 10px">清空搜索</el-button>
            </div>
            <!-- <el-divider /> -->
            <!-- 添加的课程 -->
            <div class="selected-rows-info">
              <!-- <div class="title">
                已选课程
                <el-tooltip content="此表格为已选课程，双击行数据删除" placement="right">
                  <el-icon style="vertical-align: middle; margin-left: 8px">
                    <QuestionFilled />
                  </el-icon>
                </el-tooltip>
              </div> -->
              <el-table
                :data="selectedRows"
                stripe
                border
                class="custom-table"
                style="width: 100%"
                height="200"
                @row-dblclick="SelectedHandleDblClick"
              >
                <el-table-column prop="Title" label="课程名称">
                  <template #default="{ row }">
                    <el-button type="text" @click="handleClick(row)"> {{ row.Title }}</el-button>
                  </template>
                </el-table-column>
                <el-table-column prop="Code" label="课程代码" width="120" />
                <template #empty>
                  <div class="empty-container">
                    <p style="text-align: center; width: 100%; color: #909399; font-size: 14px; line-height: 1.5">
                      未选择课程
                      <br />
                      双击左侧行数据添加
                      <br />
                      单击左侧课程名称查看
                    </p>
                  </div>
                </template>
              </el-table>
            </div>
            <!-- 排课课表 -->
            <div class="selected-rows-info">
              <el-form-item label="排课课表" class="inline-form-item">
                <el-select v-model="selectedCurriculumLabel" placeholder="请选择课程表" clearable>
                  <el-option
                    v-for="course in courseTable"
                    :key="course.year_term"
                    :label="`${course.year_term.year}-${parseInt(course.year_term.year) + 1}学年第${
                      course.year_term.semester
                    }学期`"
                    :value="`${course.year_term.year}-${course.year_term.semester}`"
                  />
                  <template #empty>
                    <div class="empty-container">
                      <p>未获取课表，请前往<a href="./myCourse" target="_blank">我的课程</a>获取</p>
                    </div>
                  </template>
                </el-select>
              </el-form-item>
            </div>
            <div class="action-buttons">
              <el-pagination :total="selectedRows.length" :page-size="selectedRows.length" layout="total" />
              <el-button Nature="info" plain @click="clearAll">清空选择</el-button>
              <el-button Nature="success" @click="goPaike" type="primary">去排课</el-button>
            </div>
          </el-form>
        </el-card>
      </div>
    </el-card>
  </div>

  <el-dialog v-model="dialogVisible" title="课程表" width="90%">
    <template #header>
      <h2 style="font-size: 35px; font-weight: bold; text-align: center">
        {{ courseInfo.Title || "暂无" }}
      </h2>
      <h4 style="text-align: center; font-size: 20px; font-weight: bold">
        {{ courseInfo.Sim.EName || "暂无" }}
      </h4>
      <div class="dialog-header">
        <el-switch v-model="showAll" active-text="显示全部" inactive-text="简略" style="margin-left: auto" />
      </div>
    </template>

    <!-- 详情显示 -->
    <div class="dialog-content">
      <!-- 左侧课程表 -->
      <div class="timetable">
        <el-table :data="processedRows" border style="width: 100%">
          <el-table-column prop="time" label="时间段" width="120" align="center">
            <template #default="{ row }">
              <div>{{ row.timeLabel }}</div>
              <div class="time-range">{{ row.timeRange }}</div>
            </template>
          </el-table-column>

          <el-table-column v-for="day in days" :key="day" :label="`周${chineseDays[day - 1]}`" align="center">
            <template #default="{ row }">
              <div v-if="row[day].length > 0">
                <el-popover placement="top" trigger="hover" v-for="(course, index) in row[day]" :key="index">
                  <template #reference>
                    <el-tag
                      class="course-tag"
                      Nature="success"
                      size="small"
                      effect="plain"
                      sffect="dark"
                      :style="{
                        backgroundColor: getColorForStudent(course.c_c),
                        border: '1px solid ' + getColorForStudent(course.c_c),
                        color: getTextColor(getColorForStudent(course.c_c))
                      }"
                    >
                      {{ displayContent(course) }}
                    </el-tag>
                  </template>
                  <div class="popover-content">
                    <p>教学班：{{ course.c_c }}</p>
                    <p>教师：{{ course.c_t }}</p>
                    <p>教室：{{ course.c_r }}</p>
                    <p>周次：{{ formatWeeks(course.c_w) }}</p>
                  </div>
                </el-popover>
              </div>
              <span v-else>-</span>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!-- 右侧课程信息 -->
      <div class="course-info">
        <el-descriptions :column="1" border label-align="right" label-class-name="custom-label">
          <el-descriptions-item label="开课单位">{{ courseInfo.Dept || "暂无" }}</el-descriptions-item>
          <el-descriptions-item label="课程性质">{{ courseInfo.Nature || "暂无" }}</el-descriptions-item>
          <el-descriptions-item label="课程代码">{{ courseInfo.Code || "暂无" }}</el-descriptions-item>
          <el-descriptions-item label="学分">{{ courseInfo.Crd || "未知" }}</el-descriptions-item>

          <el-descriptions-item label="考核方式">{{ courseInfo.Sim.Assess || "未知" }}</el-descriptions-item>
          <el-descriptions-item label="开课方式">{{ courseInfo.Sim.Format || "暂无" }}</el-descriptions-item>
          <el-descriptions-item label="教学班数量">
            <el-popover placement="right" trigger="hover" width="500px" @show="loadGradeData(courseInfo.Code)">
              <template #reference>
                <span style="font-size: 26px !important; font-weight: bold; color: #409eff; user-select: none">{{
                  courseInfo.TeachingClassCount || "0"
                }}</span>
              </template>

              <div v-loading="gradeLoading" class="grade-popover">
                <h4 style="text-align: center; font-size: 20px; font-weight: bold; margin-bottom: 10px">
                  课程成绩统计
                </h4>
                <p style="text-align: left; font-size: 12px; color: #909399; margin-bottom: 10px">
                  数据来源：<br />
                  • 基于本平台用户授权的课程成绩数据（课程名称、教师、成绩等级）匿名聚合生成；<br />
                  • 完全匿名化处理，确保个人身份信息不可追溯；<br />
                  • 统计结果受样本规模、教师授课调整等因素影响，存在合理误差范围；<br />
                  • 数据反映历史统计情况，仅供选课参考，不作为教学评估依据。
                </p>
                <div v-if="JSON.stringify(gradeData[courseInfo.Code]?.teachers) !== '{}'" class="teacher-grade">
                  <!-- 总体统计 -->
                  <div v-if="gradeData[courseInfo.Code]?.total" class="total-statistics">
                    <div class="total-header">
                      <h5 style="font-size: 16px; font-weight: bold; margin-bottom: 8px; text-align: center">
                        总体统计
                      </h5>
                      <div class="total-info">
                        <span v-if="gradeData[courseInfo.Code]?.total?.highestGrades?.length > 0" class="explain">
                          样本中评
                          <span v-for="(grade, index) in gradeData[courseInfo.Code]?.total?.highestGrades" :key="grade">
                            <span :class="`grade-${grade}`">{{ grade }}</span>
                            <span v-if="index < gradeData[courseInfo.Code]?.total?.highestGrades?.length - 1">、</span>
                          </span>
                          占比 {{ gradeData[courseInfo.Code]?.total?.maxPercentage }}
                          <!-- 占比 {{ gradeData[courseInfo.Code]?.total?.maxPercentage }} -->
                        </span>
                        <span class="total-count">总样本数: {{ gradeData[courseInfo.Code]?.total?.total }}</span>
                      </div>
                      <div class="grade-progress">
                        <div class="progress-container">
                          <div class="progress-bar-wrapper">
                            <template v-for="grade in ['优', '良', '中', '及格', '不及格'] as GradeKey[]" :key="grade">
                              <div
                                v-if="
                                  gradeData[courseInfo.Code]?.total?.percentages[grade] &&
                                  parseInt(gradeData[courseInfo.Code]?.total?.percentages[grade]) > 0
                                "
                                class="progress-segment"
                                :style="{
                                  width: gradeData[courseInfo.Code]?.total?.percentages[grade],
                                  backgroundColor: getGradeColor(grade)
                                }"
                              ></div>
                            </template>
                          </div>
                          <div class="progress-legend">
                            <template v-for="grade in ['优', '良', '中', '及格', '不及格'] as GradeKey[]" :key="grade">
                              <div
                                v-if="
                                  gradeData[courseInfo.Code]?.total?.percentages[grade] &&
                                  parseInt(gradeData[courseInfo.Code]?.total?.percentages[grade]) > 0
                                "
                                class="legend-item"
                              >
                                <div class="legend-color" :style="{ backgroundColor: getGradeColor(grade) }"></div>
                                <div class="legend-label">{{ grade }}</div>
                                <div class="legend-value">
                                  {{ gradeData[courseInfo.Code]?.total?.grades[grade] }} ({{
                                    gradeData[courseInfo.Code]?.total?.percentages[grade]
                                  }})
                                </div>
                              </div>
                            </template>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <el-divider>教师详情</el-divider>
                  <div v-for="(teacher, name) in gradeData[courseInfo.Code]?.teachers" :key="name" class="teacher-item">
                    <div class="teacher-header">
                      <span class="teacher-name">{{ name }}</span>
                      <span v-if="teacher.highestGrades.length > 0" class="explain">
                        样本中评
                        <span v-for="(grade, index) in teacher.highestGrades" :key="grade">
                          <span :class="`grade-${grade}`">{{ grade }}</span>
                          <span v-if="index < teacher.highestGrades.length - 1">、</span>
                        </span>
                        占比 {{ teacher.maxPercentage }}
                        占比 {{ teacher.maxPercentage }}
                      </span>
                      <span class="total-count">样本数: {{ teacher.total }}</span>
                    </div>
                    <div class="grade-badges">
                      <span
                        v-for="(count, grade) in teacher.grades"
                        :key="grade"
                        class="grade-tag"
                        :class="`grade-${grade}`"
                      >
                        {{ grade }} {{ count }} ({{ teacher.percentages[grade] }})
                      </span>
                    </div>
                  </div>
                </div>
                <div v-else class="no-data">
                  <p>当前课程暂无成绩数据可分析，可能由于：</p>
                  <p>• 新开课程/课程名称变更</p>
                  <p>• 本学期教师教学安排发生变更</p>
                  <p>• 该课程尚未有用户授权成绩数据</p>
                  <p>建议等待本站新用户授权数据丰富统计</p>
                  <div class="action-guide">
                    <p>如何参与数据贡献：</p>
                    <p>✅ 成绩授权：首页 → 成绩查询 → 确保成绩正常显示</p>
                    <p>✅ 课表授权：查看课表 → 确认所有学年学期课表可见</p>
                    <p>成功授权后，首页饼图悬浮信息会显示对应教师名称</p>
                  </div>
                </div>
              </div>
            </el-popover>
          </el-descriptions-item>
        </el-descriptions>
        <div class="description-item">
          <el-descriptions :column="1" border label-align="right" label-class-name="custom-label">
            <el-descriptions-item label="课程描述">{{ courseInfo.Sim.Desc || "暂无" }}</el-descriptions-item>
          </el-descriptions>
        </div>
        <div class="action-buttons">
          <el-button type="primary" @click="addToCourseSelection">加入选课</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
  <div v-if="updateLoing" class="overlay" @click.self="closeOverlay">
    <div class="progress-container">
      <el-progress
        :percentage="progress"
        type="circle"
        :status="customStatus"
        :stroke-width="8"
        :width="250"
        class="animated-progress"
      >
        <template #default>
          <div class="progress-content">
            <div v-if="progress < 100" class="loading-icon">
              <div class="spinner"></div>
            </div>
            <el-icon v-else class="success-icon"><CircleCheckFilled /></el-icon>
            <div class="progress-text">{{ progress }}%</div>
          </div>
        </template>
      </el-progress>
      <div class="loading-text">{{ progress_str }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, onMounted, onBeforeUnmount } from "vue";
  import { Loading } from "@element-plus/icons-vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import api from "../axios/api";

  // 数据定义

  interface Course {
    Dept: string;
    Nature: string;
    Code: string;
    Crd: string;
    Title: string;
    Sim: {
      Assess: string;
      EName: string;
      Format: string;
      Desc: string;
    } | null;
    ID: string;
    Time: TimeInfo[];
  }

  interface Filters {
    Dept: string;
    courseType: string;
    courseCode: string;
    Crd: string;
    courseName: string;
    Teacher: string;
    Assess: string;
  }

  interface SelectedCourse {
    Courses: Course[];
    TimeMap: {
      [key: string]: string;
    };
  }

  const isLoading = ref(false); // 是否加载中
  const selectedRows = ref<Course[]>([]); // 已选课程
  const selectedCurriculumLabel = ref<string>(""); // 选中的课程表标签
  const selectedCurriculum = ref<any>(); // 选中的课程表
  const selected_course_data = ref<SelectedCourse>();

  // 数据定义

  const updateTime = ref<string>("加载中...");
  const filters = ref<Filters>({
    // 筛选条件
    Dept: "", // 教学系
    courseType: "", // 课程性质
    courseCode: "", // 课程代码
    Crd: "", // 学分
    courseName: "", // 课程名称
    Teacher: "", // 教师
    Assess: ""
  });

  const courses = ref<Course[]>([]);

  const departments = ref<string[]>([]); // 教学系
  const courseTypes = ref<string[]>([]); // 课程性质
  const credits = ref<string[]>([]); // 学分
  const teachers = ref<string[]>([]); // 教师
  const Assess = ref<string[]>([]);

  // 计算筛选后的课程
  const filteredCourses = computed(() => {
    isLoading.value = true;
    const result = courses.value.filter((course: any) => {
      // 检查教师筛选条件
      const teacherMatch =
        !filters.value.Teacher ||
        course.Time.some((slot: any) => {
          // 遍历 Time 中的每个时间段（排除 't' 属性）
          return Object.keys(slot)
            .filter(key => key !== "t") // 排除表示时间段的 't' 字段
            .some(weekDay =>
              // 检查该时间段内是否有教师匹配
              slot[weekDay].some((entry: any) => entry.c_t.includes(filters.value.Teacher))
            );
        });

      return (
        (!filters.value.Dept || course.Dept === filters.value.Dept) &&
        (!filters.value.courseType || course.Nature === filters.value.courseType) &&
        (!filters.value.courseCode || course.Code.includes(filters.value.courseCode)) &&
        (!filters.value.Crd || course.Crd === filters.value.Crd) &&
        (!filters.value.courseName || course.Title.includes(filters.value.courseName)) &&
        (!filters.value.Assess || course.Sim?.Assess === filters.value.Assess) &&
        teacherMatch // 加入教师筛选条件
      );
    });
    isLoading.value = false;
    return result;
  });

  const reset = () => {
    // 清空筛选条件
    filters.value = {
      Dept: "",
      courseType: "",
      courseCode: "",
      Crd: "",
      courseName: "",
      Teacher: "",
      Assess: ""
    };
  };
  const courseData = ref();

  const courseTable = ref(JSON.parse(localStorage.getItem("tableData") || "{}"));

  // 加载表格

  const loadTable = () => {
    isLoading.value = true;
    courseData.value = JSON.parse(localStorage.getItem("course_data") || "{}");
    // 1s后加载数据
    setTimeout(() => {
      if (courseData.value.Courses) {
        courses.value = courseData.value.Courses.map((course: any) => ({
          Dept: course.Dept,
          Nature: course.Nature,
          Crd: course.Crd,
          Code: course.Code,
          Sim: course.Sim,
          Title: course.Title,
          Time: course.Time
        }));
        // 假设 courseData.value.Timestamp 是标准的日期时间格式，例如 "2025-03-07 20:58:10"
        const timestamp = new Date(courseData.value.Timestamp); // 获取更新时间
        const now = new Date(); // 获取当前时间

        // 计算时间差（单位为毫秒）
        const timeDiff = now.getTime() - timestamp.getTime();

        // 将时间差转换为天和小时
        const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24)); // 计算天数
        const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); // 计算剩余小时数

        // 获取学年信息，例如 "2024-2025学年2学期" -> "24-25学年2学期"
        const academicYear = courseData.value.Update.split(" ")[0].replace(/20/g, "");

        // 拼接最终字符串
        updateTime.value = `数据【${academicYear}】更新于${days}天${hours}小时前 · 立即刷新`;
      }
      isLoading.value = false;
      departments.value = courses.value.map((course: Course) => course.Dept);
      courseTypes.value = courses.value.map((course: Course) => course.Nature);
      credits.value = courses.value.map((course: Course) => course.Crd);
      Assess.value = courses.value.map((course: Course) => course.Sim?.Assess || "");
      courses.value.forEach((course: Course) => {
        course.Time.forEach((time: any) => {
          Object.values(time).forEach((schedule: any) => {
            if (Array.isArray(schedule)) {
              schedule.forEach((item: any) => {
                if (item.c_t && !teachers.value.includes(item.c_t)) {
                  teachers.value.push(item.c_t);
                }
              });
            }
          });
        });
      });

      // 去重
      departments.value = [...new Set(departments.value)];
      courseTypes.value = [...new Set(courseTypes.value)];
      credits.value = [...new Set(credits.value)];
      teachers.value = [...new Set(teachers.value)];
      Assess.value = [...new Set(Assess.value)];
      // 排序
      departments.value.sort();
      courseTypes.value.sort();
      credits.value.sort();
      teachers.value.sort();
      Assess.value.sort();
      // console.log(departments.value, courseTypes.value, credits.value)
      // console.log(teachers.value)

      // 获取课表
      const selectedCourseIds = JSON.parse(localStorage.getItem("selectedCourseIds") || "[]");
      // console.log(selectedCourseIds)
      if (selectedCourseIds.length > 0) {
        selectedCourseIds.forEach((courseId: string) => {
          const course = courses.value.find((item: Course) => item.Code === courseId);
          if (course) {
            selectedRows.value.push(course);
          }
        });
        ElMessage.success("已添加推荐课程");
        // 清空selectedCourseIds
        localStorage.removeItem("selectedCourseIds");
      }
    }, 1000);
  };

  const handleDblClick = (row: Course) => {
    // 双击事件
    console.log("双击事件");
    console.log(row);
    // 判断是否存在
    const index = selectedRows.value.findIndex(item => item.Code === row.Code);
    if (index === -1) {
      selectedRows.value.unshift(row);
    } else {
      ElMessage.warning(`《${row.Title}》已添加到选择列表`);
    }
  };

  const updateDialogVisible = ref(false);
  const customStatus = computed(() => {
    return progress.value === 100 ? "success" : "primary";
  });
  const getCourseData = async () => {
    // 获取数据
    const course_res = await api.getAllCourse();
    if (course_res.status === 200) {
      console.log(course_res.data);
      localStorage.setItem("course_data", JSON.stringify(course_res.data));
      ElMessage.success("数据获取成功");
    } else {
      ElMessage.error(course_res.data.message);
    }
    loadTable();
    updateDialogVisible.value = false;
  };
  const updateCourseTable = async () => {
    const role = localStorage.getItem("role");

    if (role === "admin") {
      await startTask();
    } else {
      await getCourseData();
    }
  };
  const redirectToSEIG = () => {
    updateDialogVisible.value = false;
    window.open("http://class.seig.edu.cn:7001/sise/coursetemp/courseInfo.html");
    return;
  };
  const progress = ref(0);
  const updateLoing = ref(false);
  let ws: WebSocket;
  const progress_str = ref("");
  const startTask = async () => {
    progress.value = 0;
    updateLoing.value = true;
    updateDialogVisible.value = false;
    // ws = new WebSocket(`${import.meta.env.VITE_API_BASE_URL.replace("http://", "ws://")}/api/course/ws/updateCourse`);
    ws = new WebSocket(`ws://101.200.63.189:9676/api/course/ws/updateCourse`);

    ws.onmessage = async event => {
      const message = event.data;
      if (message.includes("progress")) {
        progress.value = parseFloat(message.match(/([\d.]+)%/)[0]);
        const total_progress = message.split(" ")[0];
        const now_progress = message.split(" ")[1];
        const course_name = message.split(" ")[2];
        progress_str.value = `${course_name}\n${now_progress}/${total_progress}`;
      } else if (message.includes("completed")) {
        progress.value = 100;
        progress_str.value = "数据更新已完成";
        ws.close();
        ElMessage.success("数据更新完成");
        await getCourseData();
        setTimeout(() => {
          updateLoing.value = false;
        }, 3000);
      }
    };
  };

  const handleClick = (row: Course) => {
    // 单击事件
    console.log("单击事件");
    console.log(row);
    const Code = row.Code;
    const course = courseData.value.Courses.find((item: any) => item.Code === Code);

    // 用于存储处理后不同的 c_c 值
    const uniqueCCs = new Set();
    // 遍历 course.Time 数组
    course.Time.forEach((slot: any) => {
      // 遍历每个 slot 中的属性
      for (const key in slot) {
        if (key !== "t" && Array.isArray(slot[key])) {
          // 遍历每个课程信息
          slot[key].forEach(courseInfo => {
            let cc = courseInfo.c_c;
            // 如果 c_c 包含 "01"，则去除
            if (cc.includes("01")) {
              cc = cc.replace("01", "");
            }
            // 将处理后的 c_c 添加到 Set 中
            uniqueCCs.add(cc);
          });
        }
      }
    });

    course.TeachingClassCount = uniqueCCs.size;
    selected_courses.value = course;
    // console.log(selected_courses.value)
    console.log(gradeData.value);
    dialogVisible.value = true;
  };

  const SelectedHandleDblClick = (row: Course) => {
    // 双击事件
    console.log("双击事件");
    console.log(row);
    selectedRows.value.splice(selectedRows.value.indexOf(row), 1);
  };

  const clearAll = () => {
    // 清空选择
    selectedRows.value = [];
  };

  onMounted(() => {
    loadTable();
    window.addEventListener("beforeunload", handleBeforeUnload);
  });
  onBeforeUnmount(() => {
    window.removeEventListener("beforeunload", handleBeforeUnload);
    if (ws) {
      ws.close();
    }
  });

  const handleBeforeUnload = (event: any) => {
    if (ws && ws.readyState === WebSocket.OPEN) {
      event.preventDefault();
      event.returnValue = "您确定要离开吗？抓取任务未完成";
    }
  };

  const closeOverlay = () => {
    if (progress.value === 100) {
      updateLoing.value = false;
    } else {
      ElMessage.error("任务未完成，请等待");
    }
  };

  interface TimeInfo {
    T1: string;
    T2: string;
    T3: string;
    T4: string;
    T5: string;
  }

  interface CourseInfo {
    Dept: string;
    Nature: string;
    Code: string;
    Crd: string;
    Title: string;
    Sim: string;
    TeachingClassCount: string;
    Time: TimeInfo[];
  }

  const selected_courses = ref<CourseInfo>();

  // 在原有script中增加课程信息计算属性
  const courseInfo: any = computed(() => {
    return selected_courses.value || {};
  });

  const dialogVisible = ref(false);
  const showAll = ref(false);
  const chineseDays = ["一", "二", "三", "四", "五", "六", "日"];

  // 获取存在的星期数
  const days = computed(() => [1, 2, 3, 4, 5, 6, 7]); // 固定显示周一到周五
  // 处理原始数据
  const processedRows = computed(() => {
    const timeMap: any = courseData.value.TimeMap;
    const rows = Object.keys(timeMap).map(t => ({
      time: t,
      timeLabel: timeMap[t].split("\r\n")[0],
      timeRange: timeMap[t].split("\r\n")[1],
      ...Object.fromEntries(Array.from({ length: 7 }, (_, i) => [i + 1, []]))
    }));
    console.log(rows);
    if (selected_courses.value) {
      selected_courses.value.Time.forEach((slot: any) => {
        // 从当前时间槽对象中提取时间信息
        const time = slot.t;
        // 在 rows 数组中查找 time 属性等于当前时间的行对象
        const row: any = rows.find((r: any) => r.time === time);

        // if (row) {
        //   // 如果找到了对应的行对象
        //   Object.keys(slot)
        //     .filter(k => k !== 't')
        //     .forEach(day => {
        //       // 将当前时间槽对象中对应日期的信息合并到行对象中对应日期的数组里
        //       row[day].push(...slot[day])
        //     })
        // }
        if (row) {
          // 如果找到了对应的行对象
          Object.keys(slot)
            .filter(k => k !== "t")
            .forEach(day => {
              // 检查 row[day] 是否为 undefined，如果是则初始化为空数组
              if (!row[day]) {
                row[day] = [];
              }
              // 检查 slot[day] 是否为 undefined，如果是则初始化为空数组
              const slotData = slot[day] || [];
              // 将当前时间槽对象中对应日期的信息合并到行对象中对应日期的数组里
              row[day].push(...slotData);
            });
        }
      });
    }
    // console.log(rows)
    return rows;
  });

  // 显示内容格式化
  const displayContent = (course: any) => {
    const content = showAll.value
      ? `${course.c_t} ${course.c_c} (${formatWeeks(course.c_w)}[${course.c_r}])`
      : `${course.c_t} ${course.c_c}`;

    return content;
  };

  // 周次格式化
  const formatWeeks = (weeks: any) => {
    if (!weeks || weeks.length === 0) return "";
    const start = weeks[0];
    const end = weeks[weeks.length - 1];
    return weeks.length === end - start + 1 ? `${start}-${end}周` : `第${weeks.join(",")}周`;
  };

  const getColorForStudent = (name: string) => {
    if (name === "" || !name) return "#fff";
    name = name.replace("01", "");
    // 简单的哈希函数
    const hash = name.split("").reduce((acc, char) => {
      return acc + char.charCodeAt(0);
    }, 0);

    // 使用哈希值生成颜色
    let color = `#${((hash * 1234567) % 0xffffff).toString(16).padStart(6, "0")}`;

    // 将 HEX 转换为 HSL
    const hexToHsl = (hex: string) => {
      hex = hex.replace("#", "");
      const r = parseInt(hex.substring(0, 2), 16) / 255;
      const g = parseInt(hex.substring(2, 4), 16) / 255;
      const b = parseInt(hex.substring(4, 6), 16) / 255;

      const max = Math.max(r, g, b);
      const min = Math.min(r, g, b);
      let h = 0,
        s = 0,
        l = (max + min) / 2;

      if (max !== min) {
        const d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
          case r:
            h = (g - b) / d + (g < b ? 6 : 0);
            break;
          case g:
            h = (b - r) / d + 2;
            break;
          case b:
            h = (r - g) / d + 4;
            break;
        }
        h /= 6;
      }

      return [h * 360, s * 100, l * 100];
    };

    // 将 HSL 转换为 HEX
    const hslToHex = (h: number, s: number, l: number) => {
      l /= 100;
      const a = (s * Math.min(l, 1 - l)) / 100;
      const f = (n: number) => {
        const k = (n + h / 30) % 12;
        const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
        return Math.round(255 * color)
          .toString(16)
          .padStart(2, "0");
      };
      return `#${f(0)}${f(8)}${f(4)}`;
    };

    // 调整亮度
    const [h, s, l] = hexToHsl(color);
    const newL = Math.min(60, l + 20); // 增加亮度，但不超过 80%

    // 返回新的颜色
    return hslToHex(h, s, newL);
  };
  // 计算亮度
  const getLuminance = (hexColor: string): number => {
    const hex = hexColor.replace("#", "");
    const r = parseInt(hex.substring(0, 2), 16) / 255;
    const g = parseInt(hex.substring(2, 4), 16) / 255;
    const b = parseInt(hex.substring(4, 6), 16) / 255;
    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  };

  // 根据背景颜色获取文字颜色
  const getTextColor = (backgroundColor: string): string => {
    const luminance = getLuminance(backgroundColor);
    return luminance > 0.5 ? "#000000" : "#ffffff";
  };

  const emptyCurriculum = ref({
    week_info: {
      date: "2000年01月01日 星期六",
      week: "1",
      week_start_date: "2000年01月01日"
    },

    schedules: [
      {
        time: "1 - 2 节\n09:00 - 10:20",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "3 - 4 节\n10:40 - 12:00",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "5 - 6 节\n12:30 - 13:50",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "7 - 8 节\n14:00 - 15:20",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "9 - 10 节\n15:30 - 16:50",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "11 - 12 节\n17:00 - 18:20",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "13 - 14 节\n19:00 - 20:20",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      },
      {
        time: "15 - 16 节\n20:30 - 21:50",
        friday: "",
        monday: "",
        sunday: "",
        tuesday: "",
        saturday: "",
        thursday: "",
        wednesday: ""
      }
    ],
    year_term: {
      year: "2000",
      semester: "1"
    }
  });

  const goPaike = () => {
    if (selectedRows.value.length === 0) {
      ElMessage.warning("请选择课程");
      return;
    }

    console.log(selectedCurriculumLabel.value === "" || selectedCurriculumLabel.value === undefined);
    const year_term = selectedCurriculumLabel.value.split("-");
    const year = year_term[0];
    const semester = year_term[1];
    selectedCurriculum.value = courseTable.value.find(
      (item: any) => item.year_term.year === year && item.year_term.semester === semester
    );
    localStorage.setItem("generate_first_open", "true");

    if (selectedCurriculumLabel.value === "" || selectedCurriculumLabel.value === undefined) {
      ElMessageBox.confirm("确定使用空课表吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        localStorage.setItem("selected_curriculum", JSON.stringify(emptyCurriculum.value));
        selected_course_data.value = {
          Courses: selectedRows.value,

          TimeMap: courseData.value.TimeMap
        };
        localStorage.setItem("selected_course_data", JSON.stringify(selected_course_data.value));
        window.open("./SchedulingCourse", "_blank");
      });
    } else {
      localStorage.setItem("selected_curriculum", JSON.stringify(selectedCurriculum.value));
      selected_course_data.value = {
        Courses: selectedRows.value,
        TimeMap: courseData.value.TimeMap
      };
      localStorage.setItem("selected_course_data", JSON.stringify(selected_course_data.value));
      window.open("./SchedulingCourse", "_blank");
    }
  };

  const addToCourseSelection = () => {
    const row = courseInfo.value;
    console.log(row);
    // 判断是否存在
    const index = selectedRows.value.findIndex(item => item.Code === row.Code);
    if (index === -1) {
      selectedRows.value.unshift(row);
    } else {
      ElMessage.warning(`《${row.Title}》已添加到选择列表`);
    }
    dialogVisible.value = false;
  };

  // 类型定义
  type GradeKey = "优" | "良" | "中" | "及格" | "不及格";
  type RawTeacherGrades = Record<GradeKey, number>;

  interface RawCourseGradeData {
    course_code: string;
    course_name: string;
    teachers: Record<string, RawTeacherGrades>;
  }

  interface TeacherGradeData {
    total: number;
    grades: RawTeacherGrades;
    percentages: Record<GradeKey, string>;
    highestGrades: GradeKey[];
    maxPercentage: string;
  }

  interface CourseGradeData {
    teachers: Record<string, TeacherGradeData>;
    total: TeacherGradeData;
  }

  // 响应式数据
  const gradeData = ref<Record<string, CourseGradeData>>({});
  const gradeLoading = ref<boolean>(false);

  // 方法实现
  const loadGradeData = async (Code: string): Promise<void> => {
    if (!gradeData.value[Code]) {
      try {
        gradeLoading.value = true;
        const res = await api.getCourseGradeTeacher(Code);
        processGradeData(Code, res.data);
      } finally {
        gradeLoading.value = false;
      }
    }
  };

  const processGradeData = (code: string, rawData: RawCourseGradeData): void => {
    // 定义处理后的课程数据结构
    const processed: CourseGradeData = {
      teachers: {},
      total: {
        total: 0,
        grades: {
          优: 0,
          良: 0,
          中: 0,
          及格: 0,
          不及格: 0
        },
        percentages: {
          优: "0%",
          良: "0%",
          中: "0%",
          及格: "0%",
          不及格: "0%"
        },
        highestGrades: [],
        maxPercentage: ""
      }
    };

    // 计算总体统计数据
    const totalGrades: RawTeacherGrades = {
      优: 0,
      良: 0,
      中: 0,
      及格: 0,
      不及格: 0
    };

    // 遍历原始数据中的教师列表
    Object.entries(rawData.teachers).forEach(([name, grades]: [string, RawTeacherGrades]) => {
      // 累加总体统计数据
      Object.entries(grades).forEach(([grade, count]) => {
        totalGrades[grade as GradeKey] += count;
      });

      // 计算评价总数
      const total: number = (Object.values(grades) as number[]).reduce((a: number, b: number) => a + b, 0);

      // 初始化百分比存储对象
      const percentages: Record<GradeKey, string> = {} as Record<GradeKey, string>;
      let maxPercentage: number = 0; // 记录最大百分比数值
      const highestGrades: GradeKey[] = []; // 存储最高占比的等级列表

      // 遍历每个评分等级（使用类型断言确保类型安全）
      (Object.entries(grades) as [GradeKey, number][]).forEach(([grade, count]: [GradeKey, number]) => {
        // 计算当前等级百分比
        const percent: number = total > 0 ? Math.round((count / total) * 100) : 0;
        percentages[grade] = `${percent}%`;

        // 更新最大百分比数据
        if (percent > maxPercentage) {
          maxPercentage = percent;
          highestGrades.splice(0, highestGrades.length, grade); // 清空并添加新最大值
        } else if (percent === maxPercentage && maxPercentage > 0) {
          highestGrades.push(grade); // 添加并列最大值
        }
      });

      // 构造教师数据结构（符合 TeacherGradeData 接口）
      const teacherData: TeacherGradeData = {
        total,
        grades,
        percentages,
        highestGrades: [...new Set(highestGrades)], // 去重处理
        maxPercentage: maxPercentage > 0 ? `${maxPercentage}%` : ""
      };

      // 存储处理后的教师数据
      processed.teachers[name] = teacherData;
    });

    // 计算总体统计的百分比
    const totalCount = Object.values(totalGrades).reduce((a, b) => a + b, 0);
    const totalPercentages: Record<GradeKey, string> = {} as Record<GradeKey, string>;
    let totalMaxPercentage = 0;
    const totalHighestGrades: GradeKey[] = [];

    Object.entries(totalGrades).forEach(([grade, count]) => {
      const percent = totalCount > 0 ? Math.round((count / totalCount) * 100) : 0;
      totalPercentages[grade as GradeKey] = `${percent}%`;

      if (percent > totalMaxPercentage) {
        totalMaxPercentage = percent;
        totalHighestGrades.splice(0, totalHighestGrades.length, grade as GradeKey);
      } else if (percent === totalMaxPercentage && totalMaxPercentage > 0) {
        totalHighestGrades.push(grade as GradeKey);
      }
    });

    // 添加总体统计数据
    processed.total = {
      total: totalCount,
      grades: totalGrades,
      percentages: totalPercentages,
      highestGrades: [...new Set(totalHighestGrades)],
      maxPercentage: totalMaxPercentage > 0 ? `${totalMaxPercentage}%` : ""
    };

    // 更新响应式数据（保留历史数据）
    gradeData.value = {
      ...gradeData.value,
      [code]: processed
    };
  };

  // 添加获取成绩等级颜色的方法
  const getGradeColor = (grade: string): string => {
    const colorMap: Record<string, string> = {
      优: "#2e7d32",
      良: "#1565c0",
      中: "#ef6c00",
      及格: "#757575",
      不及格: "#c62828"
    };
    return colorMap[grade] || "#909399";
  };
</script>

<style scoped lang="scss">
  .app-container {
    background-color: #f5f7fa;

    .main-card {
      max-width: 100%;
      height: 90vh;
      margin: 0 auto;

      :deep(.el-card__body) {
        padding: 20px;
      }
    }

    .flex-container {
      display: flex;
      gap: 24px;
    }

    .table-wrapper {
      flex: 1;
      overflow-x: auto;
      overflow-y: auto;
      max-height: 85vh;

      /* 隐藏滚动条 */
      -ms-overflow-style: none; /* IE 和 Edge */
      scrollbar-width: none; /* Firefox */

      &::-webkit-scrollbar {
        display: none; /* Chrome, Safari 和 Opera */
      }

      .custom-table {
        :deep(th.el-table__cell) {
          background-color: #f8f9fa;
        }

        :deep(.el-table__row--striped) {
          background-color: #fafafa;
        }

        /* 禁止文本选中 */
        user-select: none;

        /* 或者更具体地 */
        :deep(.el-table__cell) {
          user-select: none;
          text-align: center;
        }
      }
    }

    .filter-card {
      width: 360px;
      user-select: none;
      overflow-y: auto;
      max-height: 85vh;

      .filter-header {
        margin-bottom: 20px;

        .update-time {
          font-size: 12px;
          color: #909399;
          cursor: pointer;
          &:hover {
            color: #409eff;
          }
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }
    }

    .filter-form {
      display: flex;
      flex-direction: column;
      width: 100%;
      gap: 16px;

      .inline-form-item {
        width: 100%;
        display: flex;
        align-items: center;
        margin-bottom: 0;

        label {
          margin-right: 10px;
          flex: 0 0 100px;
          text-align: right;
        }

        .el-select,
        .el-input {
          flex: 1;
          min-width: 0;
        }
      }

      .action-buttons {
        display: flex;
        justify-content: flex-end;
        gap: 12px;
        width: 100%;
        margin-top: 8px;
      }
    }

    .selected-rows-info {
      width: 100%;
      margin-top: 16px;
      text-align: center;
      user-select: none;

      :deep(.el-table__cell) {
        user-select: none;
        text-align: center;
      }
    }
  }
  @keyframes spin {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }
  .spin-icon {
    animation: spin 1s linear infinite;
  }
  .empty-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    text-align: center;
  }

  .title {
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 10px;
  }

  .dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .time-range {
    font-size: 0.8em;
    color: #666;
  }

  .course-item {
    white-space: pre-wrap;
    padding: 5px 0;
    line-height: 1;
  }

  .popover-content p {
    margin: 5px 0;
  }

  .el-table :deep(.cell) {
    text-align: center;
  }
  .course-tag {
    margin: 2px;
    white-space: normal;
    line-height: 1.4;
    height: auto;
    padding: 4px 8px;
    display: inline-flex;
    max-width: 200px;
    text-align: center;
    /* 禁止选择 */
    user-select: none;
  }

  .el-tag + .el-tag {
    margin-left: 4px;
  }

  /* 表格整体边框 */
  :deep(.el-table) {
    border: 2px solid #ebeef5;
    border-radius: 4px;
  }

  /* 单元格通用样式 */
  :deep(.el-table td.el-table__cell),
  :deep(.el-table th.el-table__cell) {
    border-right: 2px solid #ebeef5;
    border-bottom: 2px solid #ebeef5;
  }

  /* 移除最后一列右边框 */
  :deep(.el-table__cell:last-child) {
    border-right: none;
  }

  /* 行hover效果增强 */
  :deep(.el-table__body tr:hover td) {
    border-bottom-color: #409eff;
    box-shadow: inset 0 1px 0 #409eff33;
  }
  .dialog-content {
    display: flex;
    gap: 20px;
    align-items: flex-start;
  }

  .course-info {
    width: 600px;
    min-width: 300px;
    background: #f8f9fa;
    padding: 15px;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    :deep(.el-descriptions__cell) {
      text-align: center;
    }
    .action-buttons {
      display: flex;
      justify-content: center;
      margin-top: 20px;
    }
  }

  .timetable {
    flex: 1;
    overflow-x: auto;
  }

  /* 优化描述列表样式 */
  :deep(.el-descriptions__title) {
    font-size: 16px;
    margin-bottom: 15px;
  }

  :deep(.el-descriptions__body) {
    background: transparent;
  }

  :deep(.el-descriptions-item__label) {
    width: 100px;
    background: #f5f7fa !important;
  }

  .description-item {
    :deep(.el-descriptions__content) {
      text-align: left;
      text-indent: 2em;
    }
  }
  .overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 2000;
    backdrop-filter: blur(3px);
  }

  .progress-container {
    position: relative;
    // padding: 20px;
    border-radius: 50px;
    // background: linear-gradient(45deg, #43497b, #2d2d2d);
    // box-shadow: 0 0 30px rgba(58, 143, 255, 0.3);
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .loading-text {
    color: #fff;
    font-size: 12px;
    font-weight: bold;
    margin-top: 20px;
    text-align: center;
    white-space: pre-wrap;
    line-height: 1.5;
  }

  .animated-progress :deep(.el-progress-circle__track) {
    stroke: rgba(255, 255, 255, 0.1);
  }

  .animated-progress :deep(.el-progress-circle__path) {
    transition: all 0.6s ease-out;
    stroke-linecap: round;
  }

  .progress-content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
  }

  .loading-icon {
    position: relative;
    width: 40px;
    height: 40px;
    margin: 0 auto 10px;
  }

  .spinner {
    position: absolute;
    width: 100%;
    height: 100%;
    border: 3px solid transparent;
    border-top-color: #409eff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }

  .success-icon {
    font-size: 48px;
    color: #67c23a;
    margin-bottom: 10px;
    animation: scaleIn 0.5s ease-out;
  }

  @keyframes scaleIn {
    0% {
      transform: scale(0);
    }
    80% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(1);
    }
  }

  .progress-text {
    font-size: 24px;
    font-weight: bold;
    color: #fff;
    text-shadow: 0 0 10px rgba(64, 158, 255, 0.5);
  }

  .start-button {
    font-size: 16px;
    padding: 12px 24px;
    transition: all 0.3s ease;
  }

  .start-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(64, 158, 255, 0.3);
  }

  .icon {
    margin-left: 8px;
    transition: transform 0.3s ease;
  }

  .start-button:hover .icon {
    transform: translateX(3px);
  }

  .grade-popover {
    padding: 8px 0;
    max-height: 700px;
    overflow: hidden; /* 改为 hidden，防止整体滚动 */
  }

  .teacher-grade {
    max-height: 400px; /* 设置教师列表的最大高度 */
    overflow-y: auto; /* 只允许教师列表垂直滚动 */

    /* 美化滚动条 */
    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background-color: #dcdfe6;
      border-radius: 3px;
    }

    &::-webkit-scrollbar-track {
      background-color: #f5f7fa;
      border-radius: 3px;
    }
  }

  .total-statistics {
    background: #f8f9fa;
    padding: 15px;
    border-radius: 8px;
    // margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    position: sticky; /* 使总体统计固定在顶部 */
    top: 0;
    z-index: 1;
    background: #f8f9fa;

    // .total-header {
    //   margin-bottom: 12px;
    // }

    .total-info {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 12px;
    }

    .grade-badges {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
    }
  }

  .teacher-item {
    margin-bottom: 12px;
    padding: 8px 12px;
    background: #efeeee;
    border-radius: 6px;
  }

  .grade-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }

  .grade-tag {
    font-size: 12px;
    padding: 4px 8px;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
  }

  /* 等级颜色配置 */
  .grade-优 {
    background: #e8f5e9;
    color: #2e7d32;
  }
  .grade-良 {
    background: #e3f2fd;
    color: #1565c0;
  }
  .grade-中 {
    background: #fff8e1;
    color: #ef6c00;
  }
  .grade-及格 {
    background: #cdcccc;
    color: #757575;
  }
  .grade-不及格 {
    background: #ffebee;
    color: #c62828;
  }

  .no-data {
    padding: 15px;
    background: #f8f9fa;
    border-radius: 4px;
    font-size: 14px;
  }
  .warning-icon {
    display: inline-block;
    width: 18px;
    height: 18px;
    background: #ffc107;
    border-radius: 50%;
    text-align: center;
    line-height: 18px;
    margin-right: 8px;
  }
  .reason-list {
    margin: 10px 0;
    color: #6c757d;
  }

  .highlight {
    color: #409eff;
    font-weight: 500;
  }

  .teacher-header {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 8px;
    margin-bottom: 8px;

    // 同一行显示
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .teacher-name {
    grid-column: 1 / 2;
    font-weight: 600;
  }

  .explain {
    grid-column: 1 / 3;
    font-size: 12px;
    color: #666;
  }

  .total-count {
    grid-column: 2 / 3;
    justify-self: end;
    font-size: 12px;
    color: #999;
  }
  .action-guide {
    background: #ecf5ff;
    padding: 10px;
    border-radius: 4px;
    margin-top: 10px;
  }
  .action-guide p {
    color: #409eff;
    margin-bottom: 6px;
  }
  .no-data p {
    margin-bottom: 6px;
  }

  .grade-progress {
    // margin: 10px 0;
    // padding: 10px;
    background: #f8f9fa;
    border-radius: 8px;

    .progress-container {
      .progress-bar-wrapper {
        height: 20px;
        background: #ebeef5;
        border-radius: 10px;
        overflow: hidden;
        display: flex;
        margin-bottom: 10px;
        width: 100%;
      }

      .progress-segment {
        height: 100%;
        transition: width 0.3s ease;
        min-width: 0;
      }

      .progress-legend {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
        justify-content: center;

        .legend-item {
          display: flex;
          align-items: center;
          gap: 4px;
          font-size: 12px;
          color: #606266;

          .legend-color {
            width: 12px;
            height: 12px;
            border-radius: 2px;
          }

          .legend-label {
            margin-right: 4px;
          }

          .legend-value {
            color: #909399;
          }
        }
      }
    }
  }
</style>
